package pheromoneMap;

public class Vector2D {
	private double m_xPos, m_yPos;

	/**
	 * Creates a new Vector2D with x component 0 and y component 0.
	 */
	public Vector2D() {
		this( 0, 0 );
	}
	
	/**
	 * Creates a new Vector2D with x component xPos and y component yPos.
	 * @param xPos
	 * @param yPos
	 */
	public Vector2D(double xPos, double yPos) {
		m_xPos = xPos;
		m_yPos = yPos;
		
//		this.pinMagnitude();
	}

	/**
	 * Creates a new Vector2D with components equal to the Vector2D toCopy.
	 * @param toCopy
	 */
	public Vector2D( Vector2D toCopy ) {
		this( toCopy.m_xPos, toCopy.m_yPos );
		
//		this.pinMagnitude();
	}


	/**
	 * Returns the X component of this vector.
	 * @return
	 */
	public double getX() {
		return m_xPos;
	}
	
	/**
	 * Returns the Y component of this vector.
	 * @return
	 */
	public double getY() {
		return m_yPos;
	}
	
	/**
	 * Returns the magnitude of this vector (r in polar notation)
	 * @return
	 */
	public double magnitude() {
		return Math.sqrt( (m_xPos * m_xPos) + (m_yPos * m_yPos) );
	}
	
	/**
	 * Returns the logarithmic magnitude of this vector
	 * @return
	 */
	public double logMagnitude() {
		return Math.log( this.magnitude() + 1 );
	}
	
	/**
	 * Sets the magnitude of the vector while maintaining direction.
	 */
	public void setMagnitude( double newMagnitude ) {
		if( newMagnitude >= 0 && newMagnitude < (2 * Math.PI) ) {
			double direction = this.direction();
			this.m_xPos = newMagnitude * Math.cos( direction );
			this.m_yPos = newMagnitude * Math.sin( direction );
		}
	}

	/**
	 * Returns the direction of this vector (theta in polar notation)
	 * @return
	 */
	public double direction() {
		double theta = Math.atan2( m_yPos, m_xPos );
		if( theta < 0 ) theta += 2 * Math.PI;
		
		return theta;
	}
	
	/**
	 * Sets the direction of the vector while maintaining magnitude.
	 */
	public void setDirection( double newDirection ) {
		if( newDirection >= 0 && newDirection < (2 * Math.PI) ) {
			double magnitude = this.magnitude();
			this.m_xPos = magnitude * Math.cos( newDirection );
			this.m_yPos = magnitude * Math.sin( newDirection );
		}
	}
	
	/**
	 * returns the result of this + arg1.
	 * @param arg1
	 * @return
	 */
	public Vector2D add( Vector2D arg1 ) {
		return new Vector2D( m_xPos + arg1.getX(), m_yPos + arg1.getY() );
	}
	
	/**
	 * Returns the result of this - arg1.
	 * @param arg1
	 * @return
	 */
	public Vector2D subtract( Vector2D arg1 ) {
		return new Vector2D( m_xPos - arg1.getX(), m_yPos + arg1.getY() );
	}
	
	/**
	 * Returns the result of this * arg1, where arg1 is a double-precision scalar value.
	 * @param arg1
	 * @return
	 */
	public Vector2D multiply( double arg1 ) {
		return new Vector2D( m_xPos * arg1, m_yPos * arg1 );
	}
	
	/**
	 * Updates the vector in place to be equal to the passed-in vector.
	 */
	public void update( Vector2D toCopy ) {
		this.m_xPos = toCopy.m_xPos;
		this.m_yPos = toCopy.m_yPos;
		
//		this.pinMagnitude();
	}
	
	public void clear() {
		this.m_xPos = 0;
		this.m_yPos = 0;
	}

/*	public void pinMagnitude() {
		if( this.magnitude() > MAX_MAGNITUDE ) {
			double scalingFactor = MAX_MAGNITUDE / this.magnitude();
			this.m_xPos *= scalingFactor;
			this.m_yPos *= scalingFactor;
		}
	}*/
}
